class Fraction {
    constructor(numerator, denominator = 1) {
        if (denominator === 0) {
            throw new Error("Denominator cannot be zero.");
        }

        // 简化分数
        const gcd = this.gcd(Math.abs(numerator), Math.abs(denominator));
        this.numerator = numerator / gcd;
        this.denominator = denominator / gcd;

        // 确保分母为正
        if (this.denominator < 0) {
            this.numerator *= -1;
            this.denominator *= -1;
        }
    }

    // 计算最大公约数
    gcd(a, b) {
        return b === 0 ? a : this.gcd(b, a % b);
    }

    static fromInt(i) {
        return new Fraction(i);
    }

    // 从字符串初始化分数对象，支持分数、小数和整数
    static fromString(str) {
        if (str.includes('/')) {
            // 分数字符串，例如 "3/4"
            const parts = str.split('/');
            if (parts.length !== 2) {
                throw new Error("Invalid fraction format.");
            }
            const numerator = parseInt(parts[0], 10);
            const denominator = parseInt(parts[1], 10);
            return new Fraction(numerator, denominator);
        } else if (str.includes('.')) {
        	let f = Fraction.fromRational(str);
        	if (f !== null) {
        		return f
        	}
            // 小数字符串，例如 "0.75"
            const decimal = parseFloat(str);
            if (isNaN(decimal)) {
                throw new Error("Invalid decimal format.");
            }
            // 计算小数位数
            const decimalPlaces = (str.split('.')[1] || '').length;
            const denominator = Math.pow(10, decimalPlaces);
            const numerator = decimal * denominator;
            return new Fraction(numerator, denominator);
        } else {
            // 整数字符串，例如 "5"
            const numerator = parseInt(str, 10);
            if (isNaN(numerator)) {
                throw new Error("Invalid integer format.");
            }
            return new Fraction(numerator);
        }
    }

    static fromRational(input) {
    // 正则表达式匹配浮点数，并检测循环节
    const regex = /^(-?\d+)\.(\d*?)(\d+?)\3{2,}$/;
    const match = input.match(regex);

    if (!match) {
        return null
    }

    const integerPart = match[1]; // 整数部分
    const nonRepeating = match[2]; // 非循环节部分
    const repeating = match[3]; // 循环节部分

    let numerator, denominator;

    if (repeating) {
        // 处理循环节
        const A = integerPart + nonRepeating + repeating;
        const B = integerPart + nonRepeating;

        numerator = parseFloat(A) - parseFloat(B);
        denominator = Math.pow(10, nonRepeating.length + repeating.length) - Math.pow(10, nonRepeating.length);
    } else {
    	return null
    }

    // 化简分数
    const gcdValue = gcd(numerator, denominator);
    numerator /= gcdValue;
    denominator /= gcdValue;

    return new Fraction(numerator,denominator);
}

    iszero() {
        return this.numerator == 0;
    }

    equals(f) {
        return (f.numerator == 0 && this.numerator == 0) || (f.numerator == this.numerator && f.denominator == this.denominator);
    }

    // 加法
    add(other) {
        const numerator = this.numerator * other.denominator + other.numerator * this.denominator;
        const denominator = this.denominator * other.denominator;
        return new Fraction(numerator, denominator);
    }

    // 减法
    sub(other) {
        const numerator = this.numerator * other.denominator - other.numerator * this.denominator;
        const denominator = this.denominator * other.denominator;
        return new Fraction(numerator, denominator);
    }

    // 乘法
    mul(other) {
        const numerator = this.numerator * other.numerator;
        const denominator = this.denominator * other.denominator;
        return new Fraction(numerator, denominator);
    }

    neg() {
        this.numerator *= -1;
        return this;
    }

    // 除法
    div(other) {
        if (other.numerator === 0) {
            throw new Error("Cannot divide by zero.");
        }
        const numerator = this.numerator * other.denominator;
        const denominator = this.denominator * other.numerator;
        return new Fraction(numerator, denominator);
    }

    // 转字符串
    toString() {
        if (this.denominator === 1) {
            return `${this.numerator}`;
        } else {
            return `${this.numerator}/${this.denominator}`;
        }
    }

    // 转小数
    toDecimal() {
        return this.numerator / this.denominator;
    }
}

// 计算最大公约数
function gcd(a, b) {
    a = Math.abs(a);
    b = Math.abs(b);
    while (b !== 0) {
        [a, b] = [b, a % b];
    }
    return a;
}


// 示例用法
const frac1 = Fraction.fromString("5"); // 从整数字符串初始化
const frac2 = Fraction.fromString("3/4"); // 从分数字符串初始化
const frac3 = Fraction.fromString("0.75"); // 从小数字符串初始化

console.log(frac1.toString()); // 输出 "5"
console.log(frac2.toString()); // 输出 "3/4"
console.log(frac3.toString()); // 输出 "3/4"

const sum = frac1.add(frac2);
console.log(sum.toString()); // 输出 "23/4"

const product = frac2.mul(frac3);
console.log(product.toString()); // 输出 "9/16"